//
//  HTPlayerView.swift
//  MagaCore
//
//  Created by qmdjx on 2023/5/20.
//

import SwiftUI
import AVKit
import AppLovinSDK
import Combine

struct HTPlayerView: View {
  let var_margin: CGFloat = 15
  let var_progressWidth: CGFloat = var_screenWidth - 2*15 - 22*2 - 57*2 - 16*2
  let var_progressLandsWidth: CGFloat = var_screenHeight - 60*2 - 30*2 - 12

  @Binding var var_animeInfo: HTAnime?
  @Binding var var_animeTitle: String
  @Binding var var_url: String
  @Binding var var_changeUrl: HTChangeUrl?
  @Binding var var_orientation: UIDeviceOrientation
  @Binding var var_selectEP: (() -> Void)!
  @Binding var var_nextEP: (() -> Void)!
  @Binding var var_subTitleBtnClick: (() -> Void)!
  @Binding var var_fullScreen: ((UIDeviceOrientation) -> Void)!
  @Binding var var_subtitleList: [HTSubtitle]?
  @Binding var var_subState: HTEnumSubtitleState!
  @Binding var var_palyerCurrentTime: Double!
  @Binding var var_delay: Double!
  @Binding var var_progressRate: Double!
  @Binding var var_startTime: String
  @Binding var var_seekTime: Int
  @Binding var var_during: Double
  @Binding var var_selEp: HTEp!
  @Binding var var_source: String
  @Binding var var_isLock: Bool
  @Binding var var_curSubscribe: HTSubscribe?

  @EnvironmentObject private var var_store: HTAppStore
  @State private var var_palyer = AVPlayer()
  @State private var var_isShowControls = true
  @State private var var_isSuspend = true        // 是否暂停
  @State private var var_endTime = "00:00"
  @State private var var_fastState: HTEnumFast = .htEnumNone
  @State private var var_subText = ""
  @State private var var_oldX: CGFloat = 0.0
  @State private var var_oldY: CGFloat = 0.0
  @State private var var_timeObserver: Any!
  @State private var var_pushToPremium: () -> Void = {}
  @State private var var_showPushToPremium = false
  @State private var var_showRewardedAd: Bool = false
  @State private var var_showInterstitialAd: Bool = false
  @State private var var_viewDisappear: Bool = false
  @State private var var_brightnessLevel: Double = 0.0
  @State private var var_showProgress: Bool = false
  @State private var var_showBrightness: Bool = false
  @State private var var_showVolume: Bool = false
  @State private var var_showActivityIndicator: Bool = false
  @State private var currentTime: Double = 0.0
  @State private var timer: Timer?
  @State private var timeObserver: Any?
  @State private var lastTriggeredMinute = -1

  init(var_animeInfo: Binding<HTAnime?>, var_animeTitle: Binding<String>, var_url: Binding<String>, var_changeUrl: Binding<HTChangeUrl?>, var_orientation: Binding<UIDeviceOrientation>, var_selectEP: Binding<(() -> Void)?>, var_nextEP: Binding<(() -> Void)?>, var_subTitleBtnClick: Binding<(() -> Void)?>, var_fullScreen: Binding<((UIDeviceOrientation) -> Void)?>, var_subtitleList: Binding<[HTSubtitle]?>, var_subState: Binding<HTEnumSubtitleState?>, var_palyerCurrentTime: Binding<Double?>, var_delay: Binding<Double?>, var_progressRate: Binding<Double?>, var_startTime: Binding<String>, var_seekTime: Binding<Int>, var_during: Binding<Double>, var_selEp: Binding<HTEp?>, var_source: Binding<String>, var_isLock: Binding<Bool>, var_curSubscribe: Binding<HTSubscribe?>) {
    _var_animeInfo = var_animeInfo
    _var_animeTitle = var_animeTitle
    _var_url = var_url
    _var_changeUrl = var_changeUrl
    _var_orientation = var_orientation
    _var_selectEP = var_selectEP
    _var_nextEP = var_nextEP
    _var_subTitleBtnClick = var_subTitleBtnClick
    _var_fullScreen = var_fullScreen
    _var_subtitleList = var_subtitleList
    _var_subState = var_subState
    _var_palyerCurrentTime = var_palyerCurrentTime
    _var_delay = var_delay
    _var_progressRate = var_progressRate
    _var_startTime = var_startTime
    _var_seekTime = var_seekTime
    _var_during = var_during
    _var_selEp = var_selEp
    _var_source = var_source
    _var_isLock = var_isLock
    _var_curSubscribe = var_curSubscribe
  }

  var body: some View {
    VStack(spacing: 0){
      if var_orientation.isPortrait {
        Text("").frame(width: var_screenWidth, height: var_safeTop).background(Color.black)
      }

      ZStack(alignment: .center) {
        NavigationLink(destination: HTPremiumScreen(var_isPush: true), isActive: $var_showPushToPremium) {
          EmptyView()
        }

        HTPalyer(var_palyer: $var_palyer, var_onTimeControlStatus: { newStatus in
          if newStatus == .playing || newStatus == .paused {
            var_showActivityIndicator = false
          } else {
            var_showActivityIndicator = true
          }
        })
        .onTapGesture(count: 2) {
          if var_isLock && var_orientation.isLandscape { return }
          ht_startOrSuspend()
        }
        .onTapGesture {
          print(UIDevice.ht_screenWidth(), UIDevice.ht_screenHeight())
          var_isShowControls = !var_isShowControls
        }

        // 全屏
        if var_orientation.isLandscape {
          HTControlFullView(var_palyer: $var_palyer, var_animeTitle: $var_animeTitle, var_selectEP: $var_selectEP, var_nextEP: $var_nextEP, var_subTitleBtnClick: $var_subTitleBtnClick, var_fullScreen: $var_fullScreen, var_subState: $var_subState, var_progressRate: $var_progressRate, var_startTime: $var_startTime, var_endTime: $var_endTime, var_during: $var_during, var_fastState: $var_fastState, var_isSuspend: $var_isSuspend, var_isShowControls: $var_isShowControls, var_isLock: $var_isLock, var_pushToPremium: $var_pushToPremium, var_onRemoveAd: {
            HTNetworkManager().ht_requestForBuried(.htEnumMoviePlayCl(var_movie_id: var_animeInfo!.var_id, var_movie_name: var_animeInfo!.var_title ?? "", var_kid: "32", var_source: var_source, var_eps_id: var_selEp.var_id ?? "", var_eps_name: var_selEp.var_title ?? "", var_movielist_id: "", var_secname: "", var_subtitle: "1", var_m_type: "2", var_ori_type: "2"))
          })
        }

        // 竖屏
        if var_orientation.isPortrait {
          HTControlView(var_palyer: $var_palyer, var_subTitleBtnClick: $var_subTitleBtnClick, var_fullScreen: $var_fullScreen, var_subState: $var_subState, var_progressRate: $var_progressRate, var_startTime: $var_startTime, var_endTime: $var_endTime, var_during: $var_during, var_isSuspend: $var_isSuspend, var_isShowControls: $var_isShowControls)
        }

        if var_showBrightness {
          HStack{
            Image("brightness")
              .frame(width: 24, height: 24)
              .padding(.trailing, 5)
              .padding(.leading, 15)
            ProgressView(value: var_brightnessLevel, total: 1)
              .accentColor(.white)
              .background(Color(hex: "#ffffff").opacity(0.2))
              .frame(width: 140)
              .padding(.vertical, 20)
              .padding(.trailing, 15)
          }
          .background(Color(hex: "#000000").opacity(0.5))
          .cornerRadius(8)
        }

        if var_showActivityIndicator {
          HTActivityIndicator(var_style: .medium)
        }
        
        // 字幕
        if var_subState == .htEnumOpen {
          VStack{
            Spacer()
            Text(var_subText).ht_commonTextStyle(color: Color(hex: "FFFFFF"), fontSize: 16, weight: .bold)
              .padding(.bottom, var_orientation.isPortrait ? 30 : 50)
              .padding(.leading, var_margin)
              .padding(.trailing, var_margin)
//              .lineLimit(1)
          }
          .zIndex(10)
        }

        // 左滑右滑快进快退
        if var_fastState != .htEnumNone {
          VStack(spacing: 0) {
            Group {
              if var_fastState == .htEnumForward {
                Image("fast_forward")
                  .ht_resizeToFit()
                  .frame(width: 54, height: 33)
              } else if var_fastState == .htEnumBack {
                Image("fast_back")
                  .ht_resizeToFit()
                  .frame(width: 54, height: 33)
              }
            }
            Text(Int(var_progressRate * var_during).ht_formatTimeLine() + "/" + var_endTime)
              .ht_commonTextStyle(color: Color(hex: "ffffff"), fontSize: var_h4, weight: .bold)
              .padding(.top, 5)
          }
          .zIndex(10)
        }
      }
      .frame(maxWidth: .infinity, maxHeight: .infinity)
      .background(Color.black)
      .gesture(DragGesture().onChanged({ val in
        if var_isLock && var_orientation.isLandscape { return }
        let var_width = var_orientation.isPortrait ? var_screenWidth : var_screenHeight
        let x = val.location.x
        let y = val.location.y
        let diffOldY = y - (var_oldY == 0.0 ? val.startLocation.y : var_oldY)
        let diffOldX = x - (var_oldX == 0.0 ? val.startLocation.x : var_oldX)
        var_oldX = x
        var_oldY = y

        if fabsf(Float(diffOldY)) > fabsf(Float(diffOldX)) && !var_showProgress {
          if (x > var_width / 2) { // 右侧音量
            var_showVolume = true
            let var_space: Float = 0.03 // 控制幅度
            let var_currentVolume: Float = HTTools.getSystemVolumValue()
            HTTools.setSysVolum(diffOldY <= 0 ? (var_currentVolume + var_space) : (var_currentVolume - var_space))
            if var_currentVolume < 0 {
              HTTools.setSysVolum(0)
            } else if var_currentVolume > 1 {
              HTTools.setSysVolum(1)
            }
          } else { // 左侧亮度
            var_showBrightness = true
            let var_space: CGFloat = 0.05 // 控制幅度
            UIScreen.main.brightness = diffOldY <= 0 ? (UIScreen.main.brightness + var_space) : (UIScreen.main.brightness - var_space)
            if UIScreen.main.brightness < 0 {
              UIScreen.main.brightness = 0
            } else if UIScreen.main.brightness > 1 {
              UIScreen.main.brightness = 1
            }
            var_brightnessLevel = UIScreen.main.brightness
          }
        }

        if fabsf(Float(diffOldX)) > fabsf(Float(diffOldY)) && !var_showBrightness && !var_showVolume {
          var_showProgress = true
          let var_space: CGFloat = 2 // 控制幅度
          if !var_isSuspend {
            var_palyer.pause()
          }
          var_fastState = diffOldX > 0 ? .htEnumForward : .htEnumBack
          var_progressRate += diffOldX / var_width / var_space
          if var_progressRate > 1.0 {
            var_progressRate = 1.0
          } else if var_progressRate < 0.0 {
            var_progressRate = 0.0
          }
        }
      }).onEnded({ val in
        if var_isLock && var_orientation.isLandscape { return }
        let x = val.location.x
        let y = val.location.y
        let diffY = y - val.startLocation.y
        let diffX = x - val.startLocation.x
        if fabsf(Float(diffX)) > fabsf(Float(diffY)) {
          ht_seek(second: var_during * var_progressRate)
        }
        if !var_isSuspend {
          var_palyer.play()
        }
        var_fastState = .htEnumNone
        var_oldX = 0.0
        var_oldY = 0.0
        var_showProgress = false
        var_showVolume = false
        var_showBrightness = false
      }))
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
    // 插屏广告播放
    .onReceive(NotificationCenter.default.publisher(for: HTConfig.STATIC_notification_interstitialAd), perform: { notification in
      if var_viewDisappear {return}
      if let userInfo = notification.userInfo {
        let value = userInfo["status"] as! String
        if (value == "show") {
          var_showInterstitialAd = true
          var_palyer.pause()
          var_isSuspend = true
        } else if (value == "hide") {
          var_showInterstitialAd = false
          var_palyer.play()
          var_isSuspend = false
        }
      }
    })
    // 激励视频播放
    .onReceive(NotificationCenter.default.publisher(for: HTConfig.STATIC_notification_rewardedAd), perform: { notification in
      if var_viewDisappear {return}
      if let userInfo = notification.userInfo {
        let value = userInfo["status"] as! String
        if (value == "show") {
          var_showRewardedAd = true
          var_palyer.pause()
          var_isSuspend = true
        } else if (value == "hide") {
          var_showRewardedAd = false
          var_palyer.play()
          var_isSuspend = false
        }
      }
    })
    // 开始播放
    .onReceive(NotificationCenter.default.publisher(for: .AVPlayerItemNewAccessLogEntry), perform: { obj in
      if var_viewDisappear {return}
      if (var_showRewardedAd || var_showInterstitialAd) {
        var_palyer.pause()
        var_isSuspend = true
      }
    })
    // 播放结束
    .onReceive(NotificationCenter.default.publisher(for: .AVPlayerItemDidPlayToEndTime), perform: { obj in
      if var_viewDisappear {return}
      var_isSuspend = true
      var_palyer.pause()
      HTNetworkManager().ht_requestForBuried(.htEnumPlayFinished(var_error_info: "success", var_youtubeid: var_animeInfo!.var_id , var_eps_id: var_selEp.var_id ?? "", var_play_url: var_url, var_m_type: "2"))
      if (!var_showRewardedAd && !var_showInterstitialAd) {
        var_nextEP!()
      }
    })
    // 程序进入到前台
    .onReceive(NotificationCenter.default.publisher(for: HTConfig.STATIC_notification_sceneActive), perform: { obj in
      if var_viewDisappear {return}
      var_palyer.play()
      var_isSuspend = false
    })
    .onAppear {
      var_viewDisappear = false
      if (var_palyer.rate == 0.0) {
        var_palyer.play()
        var_isSuspend = false
        var_isShowControls = false
      }

      // 切换地址回调
      var_changeUrl = {var_cloUrl in
        if var_cloUrl != "" {
          print(var_cloUrl)
          var_palyer.pause()
          ht_checkVideo(palyer: var_palyer, url: var_url)
        }
      }

      let var_timeScale = var_palyer.currentItem?.asset.duration.timescale ?? 1
      // 播放进度监听
      var_timeObserver = var_palyer.addPeriodicTimeObserver(forInterval: CMTimeMake(value: Int64(1.0), timescale: var_timeScale), queue: DispatchQueue.main) { time in
        let var_currt = Double(CMTimeGetSeconds(time))
        var_progressRate = var_currt / (var_palyer.currentItem?.asset.duration.seconds)!
        var_startTime = Int(var_currt).ht_formatTimeLine()
        var_during = var_palyer.currentItem?.asset.duration.seconds ?? 0
        var_endTime = Int(var_palyer.currentItem?.asset.duration.seconds ?? 0).ht_formatTimeLine()
        // 调整字幕时间
        let var_adjustTime = Double(var_currt) + var_delay
        var_palyerCurrentTime = var_adjustTime
        for var_sub in var_subtitleList ?? [] {
          if var_adjustTime > var_sub.var_startTime && var_adjustTime < var_sub.var_endTime {
            var_subText = var_sub.var_text
            break
          } else {
            var_subText = ""
          }
        }
      }

      var_pushToPremium = {
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
          var_showPushToPremium = true
          HTNetworkManager().ht_requestForBuried(.htEnumVipSh(var_source: "3"))
        }
      }

      ht_setupTimeObserver()
    }
    .onDisappear{
      var_viewDisappear = true
      var_isSuspend = true
      var_palyer.currentItem?.cancelPendingSeeks()
      var_palyer.currentItem?.asset.cancelLoading()
      var_palyer.removeTimeObserver(var_timeObserver as Any)
      NotificationCenter.default.removeObserver(self)
      ht_stopTimeObserver()

      if (var_animeInfo != nil) {
        HTNetworkManager().ht_requestForBuried(.htEnumMoviePlayCl(var_movie_id: var_animeInfo!.var_id , var_movie_name: var_animeInfo!.var_title ?? "", var_kid: "1", var_source: var_source, var_eps_id: var_selEp.var_id ?? "", var_eps_name: var_selEp.var_title ?? "", var_movielist_id: "", var_secname: "", var_subtitle: "1", var_m_type: "2", var_ori_type: var_orientation.isPortrait ? "1" : "2"))
      }
    }
  }

  func ht_setupTimeObserver() {
    let var_interval = CMTime(seconds: 1, preferredTimescale: CMTimeScale(NSEC_PER_SEC))
    timeObserver = var_palyer.addPeriodicTimeObserver(forInterval: var_interval, queue: DispatchQueue.main) { var_time in
      let var_currentTime = Int(CMTimeGetSeconds(var_time))
      let var_currentMinute = Int(var_currentTime / 60)
      let var_minutes = (var_store.state.var_adState.var_adConfig?.var_banner_ad_secs)! / 60

      if var_currentMinute >= var_minutes && var_currentMinute % var_minutes == 0 && var_currentMinute != lastTriggeredMinute {
        // 执行操作，例如显示提示或执行特定任务
        print("Action executed at \(var_currentMinute) minute.")
        lastTriggeredMinute = var_currentMinute
        if (var_curSubscribe == nil) {
          NotificationCenter.default.post(name: HTConfig.STATIC_notification_rewardedAd, object: nil, userInfo: ["status": "canshow"])
        }
      }
    }
  }

  func ht_stopTimeObserver() {
    if let observer = timeObserver {
      var_palyer.removeTimeObserver(observer)
      timeObserver = nil
    }
  }

  func ht_startOrSuspend() {
    if var_isSuspend {
      var_palyer.play()
      var_isSuspend = false
    } else {
      var_palyer.pause()
      var_isSuspend = true
    }
  }

  func ht_checkVideo(palyer: AVPlayer, url: String) {
    DispatchQueue.global(qos: .userInitiated).async {
      let var_asset = AVAsset(url: URL(string: url)!)
      let palyerItem = AVPlayerItem(asset: var_asset)
      for _ in var_asset.availableMediaCharacteristicsWithMediaSelectionOptions {
        if let group = var_asset.mediaSelectionGroup(forMediaCharacteristic: AVMediaCharacteristic.audible) {
          if let option = group.options.first {
            palyerItem.select(option, in: group)
          }
        }
      }
      let palyerLayer = AVPlayerLayer()
      palyer.replaceCurrentItem(with: palyerItem)
      palyerLayer.videoGravity = .resizeAspectFill
      palyerLayer.player = palyer

      DispatchQueue.main.async {
        var_endTime = Int(palyer.currentItem?.asset.duration.seconds ?? 0).ht_formatTimeLine()
        var_during = palyer.currentItem?.asset.duration.seconds ?? 0
        ht_seek(second: Float64(var_seekTime))
        if (!var_showInterstitialAd && !var_showRewardedAd) {
          var_palyer.play()
          var_isSuspend = false
          var_isShowControls = false
        }
      }
    }
  }

  // 精确定位
  func ht_seek(second: Float64) {
    let var_timeScale = var_palyer.currentItem?.asset.duration.timescale
    let var_time = CMTimeMakeWithSeconds(second, preferredTimescale: var_timeScale ?? 1)
    var_palyer.seek(to: var_time, toleranceBefore: CMTime.zero, toleranceAfter: CMTime.zero)
  }
}
